import pandas as pd
import folium as fm
from folium.plugins import MarkerCluster
import geopandas as gpd
import branca as br
from branca.element import Template, MacroElement
---------------------------------------------------------------------------
ModuleNotFoundError                       Traceback (most recent call last)
~\AppData\Local\Temp\ipykernel_10428\2798937669.py in <module>
      1 import pandas as pd
----> 2 import folium as fm
      3 from folium.plugins import MarkerCluster
      4 import geopandas as gpd
      5 import branca as br

ModuleNotFoundError: No module named 'folium'
  1. Import the data located at this link. It has information on Tech Institutes’ total vacancies, total applicants, total entrants, and total enrolled. Moreover, the institutes are geolocated.

Variable

Description

cod_mod

institute code

ltimoden_metaattencion

total vacancies

accountdeid_applicant_processadm

total applicants

summation_flaging

total entrants

sumaden_flagregistered

total enrolled

nlat_ie

latitude

nlong_ie

longitude

  • Use this shapefile to generate a Choropleth map of the total institutes’ vacancies by the department. Use the overlay function (link and JN) to intersect institutes dataset with shapefiles. You can follow this code:

data = pd.read_csv(r'../../_data/institutos1.csv')

data_geo = gpd.GeoDataFrame(data, crs = "EPSG:4326",
                            geometry=gpd.points_from_xy(data.nlong_ie,data.nlat_ie))

shp_dpt = gpd.read_file(r"../../_data/INEI_LIMITE_DEPARTAMENTAL\INEI_LIMITE_DEPARTAMENTAL.shp")

intersct_data_geo = gpd.overlay(data_geo, shp_dpt, how = "intersection")

vars_sum = ['ltimoden_metaatencion' , 'cuentadeid_postulante_procesoadm' , 'sumaden_flagingresante', 'sumaden_flagmatriculado']

tot_dpt = intersct_data_geo.groupby(['CCDD'], as_index= False)[vars_sum].sum()

tot_dpt_shp = shp_dpt.merge(tot_dpt, on = 'CCDD')
# government palace coordinates

lat_palacio = -12.0757538
long_palacio = -76.9863174
zoom_start = 5

z = fm.Map(location = [lat_palacio, long_palacio], tiles='cartodbpositron', zoom_start = zoom_start)

fm.Choropleth(
    geo_data=tot_dpt_shp,
    data=tot_dpt,
    columns=['CCDD', 'ltimoden_metaatencion'],
    key_on="feature.properties.CCDD",
    fill_color="YlOrRd",
    fill_opacity=0.8,
    line_opacity=0.2,
    legend_name="Total vacancies",
    smooth_factor=0,
    Highlight= True,
    line_color = "#0000",
    overlay=True,
    nan_fill_color = "White"  # fill white missing values
).add_to(z)
z
Make this Notebook Trusted to load map: File -> Trust Notebook
  1. Make an interactive map of markes using ‘visual_html’ function and show total vacancies, applicants, entrants, and enrolled information in a table popup. Additionally, use “university” as icon. Take this map as an example

def visual_html(i):

    html="""
        <h4>Total vacancies: </h4>""" + str(intersct_data_geo.iloc[i]['ltimoden_metaatencion']) + \
         """<h4>Applicants: </h4>""" + str(intersct_data_geo.iloc[i]['cuentadeid_postulante_procesoadm']) + \
         """<h4>Entrants:</h4>""" + str(intersct_data_geo.iloc[i]['sumaden_flagingresante']) + \
         """<h4>Enrolled:</h4>""" + str(intersct_data_geo.iloc[i]['sumaden_flagmatriculado'])
    return html
lat_palacio = -12.0757538
long_palacio = -76.9863174
zoom_start = 5

inst = fm.Map(location = [lat_palacio, long_palacio], zoom_start = zoom_start)

for i in range(0,len(intersct_data_geo)):
    html = visual_html(i)

    iframe = br.element.IFrame(html=html,width=350,height=300)
    popup = fm.Popup(iframe,parse_html=True)

    fm.Marker([intersct_data_geo['nlat_ie'].iloc[i],intersct_data_geo['nlong_ie'].iloc[i]],
              popup=popup,icon=fm.Icon(color= 'blue', icon='university', prefix="fa")).add_to(inst)

inst.save("institutes_group5.html")

inst
Make this Notebook Trusted to load map: File -> Trust Notebook
  1. Generate the ratio of applicants by vacancies and store it in a new columns called ratio_applicants_vacancies ( total applicants / total vacancies ). Then, generate a cluster map with two groups of marker clusters. The first group should be compound by those institutes where there were more applicants than vacancies. Name this group as Applicant Surplus. The second group should be compound by those institutes where there were more vacancies than applicants. Name this group as Applicant Deficit.

intersct_data_geo["ratio_applicants_vacancies"] = pd.Series(dtype=float)
intersct_data_geo["cluster_group"] = pd.Series(dtype=str)

for i, row in intersct_data_geo.iterrows():
    intersct_data_geo.loc[i, "ratio_applicants_vacancies"] = intersct_data_geo.loc[i, "cuentadeid_postulante_procesoadm"] / intersct_data_geo.loc[i, "ltimoden_metaatencion"]
    if intersct_data_geo.loc[i, "ratio_applicants_vacancies"] > 1 :
        intersct_data_geo.loc[i, "cluster_group"] = "Applicant Surplus"
    else:
        intersct_data_geo.loc[i, "cluster_group"] = "Applicant Deficit"
data_surplus = intersct_data_geo[intersct_data_geo['cluster_group'] == "Applicant Surplus"]
data_deficit = intersct_data_geo[intersct_data_geo['cluster_group'] == "Applicant Deficit"]


deficit = list(zip(data_deficit['nlat_ie'], data_deficit['nlong_ie']))
surplus = list(zip(data_surplus['nlat_ie'], data_surplus['nlong_ie']))

z = fm.Map(location = [lat_palacio, long_palacio], zoom_start = 5)
MarkerCluster( deficit, name = 'Applicant Deficit' ).add_to(z)
MarkerCluster( surplus, name = 'Applicant Surplus' ).add_to(z)
fm.LayerControl(collapsed=False).add_to(z)

z
Make this Notebook Trusted to load map: File -> Trust Notebook
  1. Generate a Circle map and plot only institutes with more applicants than vacancies. Make the radius= ratio_applicants_vacancies * 10000 . Make these circles of color green. Name the layer of circles as Applicant Surplus. Use FeatureGroup

circle_surplus = fm.Map(location = [lat_palacio, long_palacio], zoom_start = 6)

for i, row in data_surplus.iterrows():

    fm.Circle([row['nlat_ie'], row['nlong_ie']],
              radius = intersct_data_geo.loc[i, "ratio_applicants_vacancies"] *10000,
              fill=True,
              color ="Green",
              fill_color="green").add_to(circle_surplus)

feature_surplus = fm.FeatureGroup(name="Applicant Surplus")
circle_surplus.add_child(feature_surplus)
fm.LayerControl(collapsed=False).add_to(circle_surplus)

circle_surplus
Make this Notebook Trusted to load map: File -> Trust Notebook
  1. Generate a Circle map and plot only institutes with less applicants than vacancies. Make the radius= ratio_applicants_vacancies * 10000 . Make these circles of color red. Name the layer of circles as Applicant Deficit. Use FeatureGroup.

circle_deficit = fm.Map(location = [lat_palacio, long_palacio], zoom_start = 6)

for i, row in data_deficit.iterrows():

    fm.Circle([row['nlat_ie'], row['nlong_ie']],
              radius = intersct_data_geo.loc[i, "ratio_applicants_vacancies"] *10000,
              fill=True,
              color ="red",
              fill_color="red").add_to(circle_deficit)

feature_deficit = fm.FeatureGroup(name="Applicant Deficit")
circle_deficit.add_child(feature_deficit)
fm.LayerControl(collapsed=False).add_to(circle_deficit)

circle_deficit
Make this Notebook Trusted to load map: File -> Trust Notebook
  1. Generate a Circle Map that combines map 4 and 5 into a unique map. Use FeatureGroup. Additionally, generate a legend for this map indicating the color and label.

circle_final = fm.Map(location = [lat_palacio, long_palacio], zoom_start = 6)

for i, row in data_surplus.iterrows():

    fm.Circle([row['nlat_ie'], row['nlong_ie']],
              radius = intersct_data_geo.loc[i, "ratio_applicants_vacancies"] *10000,
              fill=True,
              color ="Green",
              fill_color="green").add_to(circle_final)

feature_surplus = fm.FeatureGroup(name="Applicant Surplus")
circle_final.add_child(feature_surplus)

for i, row in data_deficit.iterrows():

    fm.Circle([row['nlat_ie'], row['nlong_ie']],
              radius = intersct_data_geo.loc[i, "ratio_applicants_vacancies"] *10000,
              fill=True,
              color ="red",
              fill_color="red").add_to(circle_final)

feature_deficit = fm.FeatureGroup(name="Applicant Deficit")
circle_final.add_child(feature_deficit)

fm.LayerControl(collapsed= False).add_to(circle_final)

circle_final


template = '''
<div style="
position: fixed; 
bottom: 10px;
left: 10px;
width: 150px;
height: 120px;
z-index:9999;
font-size:12px;
<p><a style="color:black;font-size:90%;margin-left:5px;">&#9658;</a>&emsp;<b>Legend</b></p>
<p><a style="color:green;font-size:90%;margin-left:5px;">&#9679;</a>&emsp;<b>Applicant Surplus</b></p>
<p><a style="color:red;font-size:90%;margin-left:5px;">&#9679;</a>&emsp;<b>Applicant Deficit</b></p>

</div>
<div style="
position: fixed; 
bottom: 10px;
left: 10px;
width: 200px;
height: 120px; 
z-index:9998;
font-size:12px;
background-color: #ffffff;

opacity: 0.4;
">
</div>
'''

legend_html = "{% macro html(this, kwargs) %}" + template + "{% endmacro %}"
legend = br.element.MacroElement()
legend._template = br.element.Template(legend_html)
circle_final.get_root().add_child(legend)
Make this Notebook Trusted to load map: File -> Trust Notebook